package session.TX;

import entity.establishment.StakeholderPerformance;
import entity.establishment.StakeholderFood;
import entity.establishment.Stakeholder;
import entity.establishment.OutletFood;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import entity.tx.*;
import helper.tx.Helper_Outlet;
import helper.tx.Helper_Stakeholder_Food;
import java.util.ArrayList;
import java.util.Calendar;
import javax.ejb.LocalBean;
import javax.persistence.Query;

/**
 *
 * @author TWD
 */
@Stateless
public class StakeholderAccountSB implements StakeholderAccountsSBRemote {

    @PersistenceContext()
    EntityManager em;
    private Stakeholder stakeholder;
    private StakeholderFood stakeholderFood;
    private StakeholderTier tier;

    public StakeholderAccountSB() {
    }
//address, phoneNo, postalCode, category
    public boolean createStakeholder(
            String name, 
            String address,
            String phoneNo,
            String postalCode,
            String categoryDescription,
            
            Integer loyaltyPoints,
            String stakeholderTier){

        if (checkStakeholderName(name)) {
            
            //Obtain the tier
            stakeholderTier = stakeholderTier.toLowerCase();
            tier = em.find(StakeholderTier.class, stakeholderTier);
            
            //Obtain the category
            categoryDescription = categoryDescription.toLowerCase();
            String queryMessage = "SELECT c FROM Category c where LOWER(c.description) = '" + categoryDescription + "'";
            Query q = em.createQuery(queryMessage);
            List list = q.getResultList();
            if (list.isEmpty()) return false;
            Category category = (Category)list.get(0);
            
            
            //Instantiate the stakeholder 
            if(category.getType().compareToIgnoreCase("stakeholder_Food") == 0){
                stakeholder = new StakeholderFood();
                stakeholder.setCategory(category);
                System.out.println(category.getType());
            }
            else if(category.getType().compareToIgnoreCase("stakeholder_PerformanceEvent") == 0){
                //CODE FOR EVENT STAKEHOLDER HERE
                stakeholder = new StakeholderPerformance();
                stakeholder.setCategory(category);
            }

            
            //Populate the data fields. These datafields are for parent Stakeholder Class only so
            //there is no special form to create specific stakeholders.
            stakeholder.setName(name);
            stakeholder.setAddress(address);
            stakeholder.setPhoneNo(phoneNo);
            stakeholder.setPostalCode(postalCode);
            stakeholder.setStakeholderTier(tier);
            stakeholder.setLoyaltyPoints(loyaltyPoints);
            
            stakeholder.setCreateTime(Calendar.getInstance());

            stakeholder.setIsActivated(true);
            em.persist(stakeholder);
            return true;
        } else {
            return false;
        }

    }



    //Return false if stakeholder name already in use
    public boolean checkStakeholderName(String name) {
        Query q1 = em.createQuery("SELECT c FROM Stakeholder c");
        for (Object o : q1.getResultList()){
            Stakeholder stk = (Stakeholder)o;
            if(stk.getName().equalsIgnoreCase(name)) return false;
        }
        return true;
        
    }

    public boolean deleteStakeholder(String name) {
        boolean bool = true;	
        stakeholder = findStakeholderByName(name);
	
		
        if (stakeholder == null) {
            return false;
        } else {
            Query q1 = em.createQuery("SELECT c FROM StakeholderBill c WHERE c.stakeHolderName = :paramName");
            q1.setParameter("paramName", name);

            List resultList = q1.getResultList();

            if (!resultList.isEmpty()) {
                for (Object o : q1.getResultList()) {
                    StakeholderBill bill = (StakeholderBill) o;
                    if (bill.isHasPaid()) {
                        bool = false;
                    }
                }
            }
            if (bool == true) {
                stakeholder.setStakeholderTier(null);
                stakeholder.setIsActivated(false);
                //em.remove(stakeholder);
                System.out.println("StakeholderAccountsBean: Stakeholder is now flagged inactive: " + stakeholder.getName());
                return true;
            } else {
                return false;
            }
        }
    }

    public boolean changeStakeholderTier(String stringTier, String name) {
        try {

            tier = em.find(StakeholderTier.class, stringTier);
            stakeholder = findStakeholderByName(name);
            stakeholder.setStakeholderTier(tier);
            em.flush();
            return true;

        } catch (Exception ex) {
            return false;
        }
    }
    
    public void changeStakeholderAnalyticSubscription(boolean flag, String name){
        Stakeholder stkhldr = this.findStakeholderByName(name);
        stkhldr.setPurchaseBI(flag);
        em.flush();   
    }

    public List<Stakeholder> getAllStakeholders() {
        Query query = em.createQuery("SELECT e FROM Stakeholder e WHERE e.isActivated = :paramActivation");
        query.setParameter("paramActivation", true);
        return query.getResultList();
    }

    public List<Helper_Stakeholder_Food> getAllStakeholderFoodHelper() {
        Query query = em.createQuery("SELECT s FROM StakeholderFood s WHERE s.isActivated = :paramActivation");
        query.setParameter("paramActivation", true);
        List<StakeholderFood> stakeholders = query.getResultList();
        List<Helper_Stakeholder_Food> returnList = new ArrayList<Helper_Stakeholder_Food>();
        for (StakeholderFood s : stakeholders) {
            Helper_Stakeholder_Food aStakeholder = new Helper_Stakeholder_Food(s.getName());
            returnList.add(aStakeholder);
            List<OutletFood> outs = (List<OutletFood>) s.getOutlets();
            if (outs == null) {
                continue;
            }
            for (OutletFood o : outs) {
                aStakeholder.addOutlet(new Helper_Outlet(o.getId(), o.getOutletName(), o.getBlkNo(), o.getStreetName(), o.getUnitName(), o.getPostalCode(),
                    s.getName(), o.getPhoneNo(),o.getLeadTime_Day(),o.getBookingWindow()));
            }
        }
        return returnList;
    }

    public List<Stakeholder> getSpecificStakeholders(String name) {
        Query query = em.createQuery("SELECT OBJECT(e) FROM Stakeholder e where LOCATE(:name, e.name)>0 AND e.isActivated = :paramActivation");
        query.setParameter("name", name);
        query.setParameter("paramActivation", true);
        return query.getResultList();
    }
    
    

    public List<Helper_Outlet> getOutletsByStakeholder(String sname) {
        Query query = em.createQuery("SELECT s FROM StakeholderFood s WHERE s.name = :sname");
        query.setParameter("sname", sname);
        List<StakeholderFood> sList = query.getResultList();
        if (sList == null || sList.isEmpty()){
            return null;
        }
        StakeholderFood s = sList.get(0);
        List<OutletFood> list = s.getOutlets();
        List<Helper_Outlet> returnList = new ArrayList<Helper_Outlet>();
        for (OutletFood o : list) {
            returnList.add(new Helper_Outlet(o.getId(), o.getOutletName(), o.getBlkNo(), o.getStreetName(), o.getUnitName(), o.getPostalCode(),
                    s.getName(), o.getPhoneNo(),o.getLeadTime_Day(),o.getBookingWindow()));
        }
        System.out.println(returnList);
        return returnList;
    }

    //Randall added: 19-oct-2011
    public void givePointsToStakeholder(String stakeholderName, int pointsToGive) {
        System.out.println(">>> StakeholderAccountsBean: Awarding points to stakeholder...");
        stakeholder = findStakeholderByName(stakeholderName);
        if (stakeholder == null) {
            System.out.println(">>> StakeholderAccountsBean: Unable to find stakeholder");
            return;
        }
        int points = stakeholder.getLoyaltyPoints() + pointsToGive;
        stakeholder.setLoyaltyPoints(points);
        em.flush();
    }
	
	public StakeholderFood findStakeholder(Long id) {
            StakeholderFood s = em.find(StakeholderFood.class, id);
            return s;
        }
	
	public Stakeholder findStakeholderByName(String stakeholderName){
		Query q = em.createQuery("SELECT c FROM Stakeholder c WHERE c.name = :paramName AND c.isActivated = :paramActivation");
		q.setParameter("paramName", stakeholderName);
                q.setParameter("paramActivation", true);
		List resultList = q.getResultList();
		if(resultList.isEmpty()) return null;
		 
		
                Stakeholder stk = (Stakeholder) resultList.get(0);
		return stk;
	}
	
	
	
	
}
